home *** CD-ROM | disk | FTP | other *** search
- /*
- * LuCe.c Modulo Kernel per Linux per tenere
- * d'occhio il sistema, ed aggiungere
- * sicurezza 'al volo' ad un 'running'
- * preesistente. Contiene una semplice
- * implementazione dei securelevel BSD
- * in attesa dell'arrivo ufficiale con
- * le Linux Capabilities [POSIX 1.e]
- * nel kernel 2.4.x di solide ACL.
- * Per maggiori informazioni leggete
- * il relativo articolo sul numero 8
- * di BFi, liberamente prelevabile e
- * consultabile dal seguente URL:
- *
- * ---[ http://www.s0ftpj.org/bfi/ ]---
- *
- * __NO__(C)2000 FuSyS [S0ftPj|BFi]
- * <fusys@s0ftpj.org>
- *
- *
- * Compilate con: gcc -c -O2 -fomit-frame-pointer LuCe.c
- * Installate con: insmod LuCe.o <secure=level>
- *
- * 3l33t quote: "wow, e funzica anche su Solaris ?"
- * Tnx'n'credits: 4.4BSD, Daemon9(Hardening the ...),
- * Pragmatic(LKM paper), BFi
- *
- */
-
- #define MODULE
- #define __KERNEL__
- #include <linux/module.h>
- #include <linux/fs.h>
- #include <linux/ext2_fs.h>
- #include <linux/dcache.h>
- #include <linux/kdev_t.h>
- #include <linux/types.h>
- #include <linux/stat.h>
- #include <linux/fcntl.h>
- #include <linux/mm.h>
- #include <sys/syscall.h>
- #include <asm/uaccess.h>
- #include <asm/unistd.h>
- #include <asm/segment.h>
-
- #define LKMNAME "LuCe"
- #define DISK 6
-
- volatile int secure=0;
- MODULE_PARM(secure, "i");
-
- char *protetti[10]={"/etc/passwd", "/etc/shadow", "/dev/mem", "/dev/kmem", NULL,
- NULL, NULL, NULL, NULL, NULL};
- struct inode luxes[10];
-
- extern void *sys_call_table[];
- int (*old_open)(const char*, int, mode_t);
- int (*old_unlink)(const char*);
- int (*old_ioctl) (unsigned int, unsigned int, unsigned long);
- int (*old_umount)(char*, int);
- int (*old_mount)(char*, char*, char*, unsigned long, void*);
- int (*old_execve)(struct pt_regs);
- int (*old_query_module)(const char *, int, char *, size_t, size_t *);
- unsigned long (*old_create_module)(const char*, size_t);
-
- int inocpy(struct inode * inode, struct inode *dest)
- {
- if (!dest) return -EFAULT;
- memcpy(dest,inode,sizeof(struct inode));
- return 0;
- }
-
- int inocmp(struct inode *in1, struct inode *in2)
- {
- if (kdev_t_to_nr(in1->i_dev)!=kdev_t_to_nr(in2->i_dev)) return 1;
- if (in1->i_ino!=in2->i_ino) return 1;
- return 0;
- }
-
- /* ~linux/fs/stat.c */
- int do_revalidate(struct dentry *dentry)
- {
- struct inode *inode = dentry->d_inode;
- if(inode->i_op && inode->i_op->revalidate)
- return inode->i_op->revalidate(dentry);
- return 0;
- }
-
- /* ~linux/fs/namei.c */
- struct dentry *kernelnamei(const char *name)
- {
- struct dentry *dentry;
-
- dentry=lookup_dentry(name, NULL, 1);
- if(!IS_ERR(dentry)){
- if(!dentry->d_inode){
- dput(dentry);
- dentry = ERR_PTR(-ENOENT);
- }
- }
- return dentry;
- }
-
- /* ~linux/fs/namei.c */
- void get_lux_inode(const char *name, struct inode *inode)
- {
- struct dentry *dentry;
- int error;
-
- dentry = kernelnamei(name);
- error=PTR_ERR(dentry);
- if(!IS_ERR(dentry)){
- error = do_revalidate(dentry);
- if(!error) inocpy(dentry->d_inode, inode);
- dput(dentry);
- }
- }
-
- void get_luxes()
- {
- int i=0;
-
- while(protetti[i] && i<10) {
- get_lux_inode(protetti[i], &luxes[i]);
- i++;
- }
- }
-
- int lux_open(const char *filename, int flags, int mode)
- {
- int i=0;
- struct inode lux;
- char *name;
-
- if(current->pid != 1 || current->p_opptr->pid != 1){
- name=getname(filename);
- get_lux_inode(name, &lux);
-
- while(protetti[i]){
- if(!inocmp(&lux, &luxes[i])){
- if(flags & (O_RDWR|O_WRONLY)){
- printk(KERN_INFO
- "LuCe: Tentativo di Scrittura su %s mediante %s [UID %d TTY %s]\n",
- filename, current->comm, current->uid,
- current->tty->driver.driver_name);
- putname(name);
- return -EACCES;
- }
- }
- i++;
- }
-
- if(secure) {
- if((S_ISBLK(lux.i_mode))&&(lux.i_gid==DISK)){
- if(flags & (O_RDWR|O_WRONLY)){
- if(current->pid != 1 || current->p_opptr->pid != 1){
- printk(KERN_INFO
- "LuCe: Accesso Raw al disco %s mediante %s [UID %d TTY %s]\n",
- filename, current->comm, current->uid,
- current->tty->driver.driver_name);
- putname(name);
- return -EACCES;
- }
- }
- }
- }
- }
- return (*old_open)(filename, flags, mode);
- }
-
- int lux_unlink(const char *pathname)
- {
- int i=0;
- struct inode lux;
- char *name;
-
- name=getname(pathname);
- get_lux_inode(name, &lux);
-
- while(protetti[i]){
- if(!inocmp(&lux, &luxes[i])){
- printk(KERN_INFO
- "LuCe: Tentativo di Unlink su %s mediante %s [UID %d TTY %s]\n",
- pathname, current->comm, current->uid, current->tty->driver.driver_name);
- putname(name);
- return -EACCES;
- }
- i++;
- }
- putname(name);
- return (*old_unlink)(pathname);
- }
-
- int lux_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
- {
- unsigned int flags;
- struct file *f;
-
- if(cmd == EXT2_IOC_SETFLAGS){
- f=current->files->fd[fd];
- if(get_user(flags, (int *)arg)) return -EFAULT;
- if(secure){
- if(((flags&(EXT2_APPEND_FL|EXT2_IMMUTABLE_FL))^
- (f->f_dentry->d_inode->u.ext2_i.i_flags&(EXT2_APPEND_FL|EXT2_IMMUTABLE_FL)))){
- printk(KERN_INFO
- "LuCe: Tentativo di Modifica %s su %s mediante %s [UID %d TTY %s]\n",
- (flags&(EXT2_APPEND_FL))?"EXT2_APPEND_FL":"EXT2_IMMUTABLE_FL",
- f->f_dentry->d_name.name, current->comm, current->uid,
- current->tty->driver.driver_name);
- return -EPERM;
- }
- else return (*old_ioctl)(fd, cmd, arg);
- }
- }
- return (*old_ioctl)(fd, cmd, arg);
- }
-
- int lux_umount(char *name, int flags)
- {
- if(secure){
- printk(KERN_INFO
- "LuCe: Tentativo di Umount su %s [UID %d TTY %s]\n", name,
- current->uid, current->tty->driver.driver_name);
- return -EPERM;
- }
- return (*old_umount)(name, flags);
- }
-
- int lux_mount(char * dev_name, char * dir_name, char * type,
- unsigned long new_flags, void * data)
- {
- if(secure){
- printk(KERN_INFO
- "LuCe: Tentativo di Mount su %s [UID %d TTY %s]\n", dev_name,
- current->uid, current->tty->driver.driver_name);
- return -EPERM;
- }
- return (*old_mount)(dev_name, dir_name, type, new_flags, data);
- }
-
- int lux_execve(struct pt_regs regs)
- {
- char *filename;
- char **argvs;
- int error;
-
- filename=getname((char *) regs.ebx);
- argvs = (char **)regs.ecx;
- error = PTR_ERR(filename);
- if (IS_ERR(filename)) return error;
- if(strstr(filename, "/sbin/init")){
- if((strstr(argvs[1], "6"))||(strstr(argvs[1], "0"))){
- printk(KERN_INFO "LuCe: Chiusura del Sistema\n");
- secure = 0;
- }
- }
- error = do_execve(filename,(char **)regs.ecx,(char **)regs.edx,®s);
- if (error == 0) current->flags &= ~PF_DTRACE;
- putname(filename);
- return error;
- }
-
- void ttycredit(char *str)
- {
- struct tty_struct *mytty;
-
- if((mytty = current->tty) != NULL) {
- (*(mytty->driver).write)(mytty, 0, str, strlen(str));
- }
- }
-
- unsigned long lux_create_module(const char *name, size_t size)
- {
- if(secure){
- printk(KERN_INFO
- "LuCe: Tentativo di Caricamento Modulo %s [UID %d TTY %s]\n",
- name, current->uid, current->tty->driver.driver_name);
- return -EPERM;
- }
- else return (*old_create_module)(name, size);
- }
-
- int new_query_module(const char *name, int which, char *buf, size_t bufsize,
- size_t *ret)
- {
- int res, cnt, errno=0;
- char *ptr, *match;
-
- res = (*old_query_module)(name, which, buf, bufsize, ret);
-
- if(res == -1)
- return(-errno);
-
- if(which != QM_MODULES)
- return(res);
-
- ptr = buf;
-
- for(cnt = 0; cnt < *ret; cnt++) {
- if(!strcmp(LKMNAME, ptr)) {
- match = ptr;
- while(*ptr)
- ptr++;
- ptr++;
- memcpy(match, ptr, bufsize - (ptr - (char *)buf));
- (*ret)--;
- return(res);
- }
- while(*ptr)
- ptr++;
- ptr++;
- }
-
- return(res);
- }
-
- int init_module(void)
- {
- EXPORT_NO_SYMBOLS;
-
- get_luxes();
- old_open = sys_call_table[SYS_open];
- sys_call_table[SYS_open] = (void *) lux_open;
- old_unlink = sys_call_table[SYS_unlink];
- sys_call_table[SYS_unlink] = (void *) lux_unlink;
- old_ioctl = sys_call_table[SYS_ioctl];
- sys_call_table[SYS_ioctl] = (void *) lux_ioctl;
- old_umount = sys_call_table[SYS_umount];
- sys_call_table[SYS_umount] = (void *) lux_umount;
- old_mount = sys_call_table[SYS_mount];
- sys_call_table[SYS_mount] = (void *) lux_mount;
- old_execve = sys_call_table[SYS_execve];
- sys_call_table[SYS_execve] = (void *) lux_execve;
- old_create_module = sys_call_table[SYS_create_module];
- sys_call_table[SYS_create_module] = (void *) lux_create_module;
- old_query_module = sys_call_table[SYS_query_module];
- sys_call_table[SYS_query_module]=(void *) new_query_module;
-
- ttycredit("\n\033[1;32mLuCe \033[1;34m[Linux 2.2.x LKM] by FuSyS [S0ftPj|BFi]\033[0m\r\n\r\n");
- printk(KERN_INFO "LuCe LKM Attivato\n");
- return 0;
- }
-
- void cleanup_module(void)
- {
- sys_call_table[SYS_open] = old_open;
- sys_call_table[SYS_unlink] = old_unlink;
- sys_call_table[SYS_ioctl] = old_ioctl;
- sys_call_table[SYS_umount] = old_umount;
- sys_call_table[SYS_mount] = old_mount;
- sys_call_table[SYS_execve] = old_execve;
- sys_call_table[SYS_create_module] = old_create_module;
- sys_call_table[SYS_query_module] = old_query_module;
- ttycredit("\n\033[1;34mLuCe LKM Disattivato\033[0m\r\n\r\n");
- printk(KERN_INFO "LuCe LKM Disattivato\n");
- }
-